<!DOCTYPE html>
<html lang="en">
<head>
  <title>Vert.x-Stomp - Vert.x</title>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta content="width=device-width, initial-scale=1.0" name="viewport">
  <meta content="Vert.x is a tool-kit for building reactive applications on the JVM." name="description">
  <link href="http://vertx.io/stylesheets/docs.css" media="screen" rel="stylesheet">
  <link href="http://vertx.io/stylesheets/font-awesome.min.css" media="screen" rel="stylesheet">
  <link href="http://vertx.io/javascripts/styles/rainbow.min.css" media="screen" rel="stylesheet">
  <!-- IE 6-8 support of HTML 5 elements -->
  <!--[if lt IE 9]>
  <script src="http://static.jboss.org/theme/js/libs/html5/pre3.6/html5.min.js"></script>
  <![endif]-->

  <link rel="apple-touch-icon" sizes="57x57" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-57x57.png">
  <link rel="apple-touch-icon" sizes="60x60" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-60x60.png">
  <link rel="apple-touch-icon" sizes="72x72" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-72x72.png">
  <link rel="apple-touch-icon" sizes="76x76" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-76x76.png">
  <link rel="apple-touch-icon" sizes="114x114" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-114x114.png">
  <link rel="apple-touch-icon" sizes="120x120" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-120x120.png">
  <link rel="apple-touch-icon" sizes="144x144" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-144x144.png">
  <link rel="apple-touch-icon" sizes="152x152" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-152x152.png">
  <link rel="apple-touch-icon" sizes="180x180" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-180x180.png">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/favicon-32x32.png" sizes="32x32">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/android-chrome-192x192.png" sizes="192x192">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/favicon-96x96.png" sizes="96x96">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/favicon-16x16.png" sizes="16x16">
  <link rel="manifest" href="http://vertx.io/assets/favicons/vertx-favicon-7/manifest.json">
  <link rel="mask-icon" href="http://vertx.io/assets/favicons/vertx-favicon-7/safari-pinned-tab.svg" color="#5bbad5">
  <meta name="msapplication-TileColor" content="#7d3194">
  <meta name="msapplication-TileImage" content="http://vertx.io/assets/favicons/vertx-favicon-7/mstile-144x144.png">
  <meta name="theme-color" content="#ffffff">

  <link href="http://fonts.googleapis.com/css?family=Ubuntu:400,500,700,400italic" rel="stylesheet" type="text/css">
  <link rel="alternate" type="application/rss+xml" title="RSS"
     href="http://vertx.io/feed.xml">
  <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    ga('create', 'UA-30144458-1', 'auto');
    ga('create', 'UA-71153120-1', 'auto', 'tracker');
    ga('send', 'pageview');
    ga('tracker.send', 'pageview');
  </script>
</head>
<body>

<a href="http://www.reactivemanifesto.org/" id="reactive-manifesto-banner">
  <img style="border: 0; position: fixed; right: 0; top:0; z-index: 9000"
    src="http://d379ifj7s9wntv.cloudfront.net/reactivemanifesto/images/ribbons/we-are-reactive-black-right.png">
</a>

<a id="skippy" class="sr-only sr-only-focusable" href="#content"><div class="container"><span class="skiplink-text">Skip to main content</span></div></a>

<header class="navbar navbar-default navbar-static-top" id="top" role="banner">
  <div class="container">
    <div class="navbar-header">
      <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#vertx-navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a href="http://vertx.io/" class="navbar-brand"><img alt="Brand" src="http://vertx.io/assets/logo-sm.png"></a>
    </div>
    <nav class="collapse navbar-collapse" id="vertx-navbar-collapse">
      <ul class="nav navbar-nav navbar-right">
        <li><a href="http://vertx.io/download/">Download</a></li>
        <li><a href="http://vertx.io/docs/">Documentation</a></li>
        <li><a href="https://github.com/vert-x3/wiki/wiki">Wiki</a></li>
        <li><a href="http://vertx.io/community/">Community</a></li>
        <li><a href="http://vertx.io/materials/">Materials</a></li>
        <li><a href="http://vertx.io/blog/">Blog</a></li>        
      </ul>
    </nav>
  </div>
</header>



  <div class="page-header" id="content">
    <div class="container">
      <div class="row">
        <div class="col-sm-12">
          <h1>Vert.x-Stomp</h1>
          
        </div>
      </div>
    </div>
  </div>




<div id="content">
  <div class="container docs-content">
    <div class="row">
      <div class="col-sm-12 col-md-push-9 col-md-3 hidden-xs hidden-sm">
        <div id="sidebar" data-spy="affix">
          <ul class="sectlevel1">
<li><a href="#_using_vertx_stomp">Using vertx-stomp</a></li>
<li><a href="#_stomp_server">STOMP server</a>
<ul class="sectlevel2">
<li><a href="#_creating_a_stomp_server">Creating a STOMP server</a></li>
<li><a href="#_closing_a_stomp_server">Closing a STOMP server</a></li>
<li><a href="#_configuration">Configuration</a></li>
<li><a href="#_subscriptions">Subscriptions</a></li>
<li><a href="#_type_of_destinations">Type of destinations</a></li>
<li><a href="#_providing_your_own_type_of_destination">Providing your own type of destination</a></li>
<li><a href="#_acknowledgment">Acknowledgment</a></li>
<li><a href="#_customizing_the_stomp_server">Customizing the STOMP server</a></li>
</ul>
</li>
<li><a href="#_stomp_client">STOMP client</a>
<ul class="sectlevel2">
<li><a href="#_creating_a_stomp_client">Creating a STOMP client</a></li>
<li><a href="#_closing_a_stomp_client">Closing a STOMP client</a></li>
<li><a href="#_handling_errors">Handling errors</a></li>
<li><a href="#_configuration_2">Configuration</a></li>
<li><a href="#_subscribing_to_destinations">Subscribing to destinations</a></li>
<li><a href="#_sending_messages">Sending messages</a></li>
<li><a href="#_acknowledgements">Acknowledgements</a></li>
<li><a href="#_transactions">Transactions</a></li>
<li><a href="#_receipt">Receipt</a></li>
</ul>
</li>
<li><a href="#_using_the_stomp_server_as_a_bridge_to_the_vert_x_event_bus">Using the STOMP server as a bridge to the vert.x Event Bus</a></li>
<li><a href="#_using_the_stomp_server_with_web_sockets">Using the STOMP server with web sockets</a></li>
<li><a href="#_registering_received_and_writing_frame_handlers">Registering received and writing frame handlers</a></li>
</ul>
        </div>
      </div>
      <div class="col-sm-12 col-md-pull-3 col-md-9">
        <div class="toc hidden-md hidden-lg">
          <h2>Table of Contents</h2>
          <ul class="sectlevel1">
<li><a href="#_using_vertx_stomp">Using vertx-stomp</a></li>
<li><a href="#_stomp_server">STOMP server</a>
<ul class="sectlevel2">
<li><a href="#_creating_a_stomp_server">Creating a STOMP server</a></li>
<li><a href="#_closing_a_stomp_server">Closing a STOMP server</a></li>
<li><a href="#_configuration">Configuration</a></li>
<li><a href="#_subscriptions">Subscriptions</a></li>
<li><a href="#_type_of_destinations">Type of destinations</a></li>
<li><a href="#_providing_your_own_type_of_destination">Providing your own type of destination</a></li>
<li><a href="#_acknowledgment">Acknowledgment</a></li>
<li><a href="#_customizing_the_stomp_server">Customizing the STOMP server</a></li>
</ul>
</li>
<li><a href="#_stomp_client">STOMP client</a>
<ul class="sectlevel2">
<li><a href="#_creating_a_stomp_client">Creating a STOMP client</a></li>
<li><a href="#_closing_a_stomp_client">Closing a STOMP client</a></li>
<li><a href="#_handling_errors">Handling errors</a></li>
<li><a href="#_configuration_2">Configuration</a></li>
<li><a href="#_subscribing_to_destinations">Subscribing to destinations</a></li>
<li><a href="#_sending_messages">Sending messages</a></li>
<li><a href="#_acknowledgements">Acknowledgements</a></li>
<li><a href="#_transactions">Transactions</a></li>
<li><a href="#_receipt">Receipt</a></li>
</ul>
</li>
<li><a href="#_using_the_stomp_server_as_a_bridge_to_the_vert_x_event_bus">Using the STOMP server as a bridge to the vert.x Event Bus</a></li>
<li><a href="#_using_the_stomp_server_with_web_sockets">Using the STOMP server with web sockets</a></li>
<li><a href="#_registering_received_and_writing_frame_handlers">Registering received and writing frame handlers</a></li>
</ul>
        </div>
        <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>STOMP is the Simple (or Streaming) Text Orientated Messaging Protocol.</p>
</div>
<div class="paragraph">
<p>STOMP
provides an interoperable wire format so that STOMP clients can communicate with any STOMP message broker to
provide easy and widespread messaging interoperability among many languages, platforms and brokers. Get more details about STOMP on <a href="https://stomp.github.io/index.html" class="bare">https://stomp.github.io/index.html</a>.</p>
</div>
<div class="paragraph">
<p>Vertx-Stomp is an implementation of a STOMP server and client. You can use the STOMP server with other clients and
use the STOMP client with other servers. The server and the client supports the version 1.0, 1.1 and 1.2 of the
STOMP protocol (see <a href="https://stomp.github.io/stomp-specification-1.2.html" class="bare">https://stomp.github.io/stomp-specification-1.2.html</a>). The STOMP server can also be used as a
bridge with the vert.x event bus, or directly with web sockets (using StompJS).</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_using_vertx_stomp">Using vertx-stomp</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To use the Vert.x Stomp server and client, add the following dependency to the <em>dependencies</em> section of your build
descriptor:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Maven (in your <code>pom.xml</code>):</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
  &lt;groupId&gt;io.vertx&lt;/groupId&gt;
  &lt;artifactId&gt;vertx-stomp&lt;/artifactId&gt;
  &lt;version&gt;3.3.3&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>Gradle (in your <code>build.gradle</code> file):</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-groovy" data-lang="groovy">compile 'io.vertx:vertx-stomp:3.3.3'</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_stomp_server">STOMP server</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_creating_a_stomp_server">Creating a STOMP server</h3>
<div class="paragraph">
<p>The simplest way to create an STOMP server, using all default options is as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx).handler(VertxStomp::StompServerHandler.create(vertx)).listen()</code></pre>
</div>
</div>
<div class="paragraph">
<p>This creates a STOMP server listening on <code>localhost:61613</code> that is compliant with the STOMP specification.</p>
</div>
<div class="paragraph">
<p>You can configure the port and host in the <code><a href="../../yardoc/VertxStomp/StompServer.html#listen-instance_method">listen</a></code>
method:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx).handler(VertxStomp::StompServerHandler.create(vertx)).listen(1234, "0.0.0.0")</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you pass <code>-1</code> as port, the TCP server would not be started. This is useful when using the websocket
bridge. To be notified when the server is ready, use a handler as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx).handler(VertxStomp::StompServerHandler.create(vertx)).listen() { |ar_err,ar|
  if (ar_err != nil)
    puts "Failing to start the STOMP server : #{ar_err.get_message()}"
  else
    puts "Ready to receive STOMP frames"
  end
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The handler receive a reference on the <code><a href="../../yardoc/VertxStomp/StompServer.html">StompServer</a></code>.</p>
</div>
<div class="paragraph">
<p>You can also configure the host and port in <code><a href="../dataobjects.html#StompServerOptions">StompServerOptions</a></code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx, {
  'port' =&gt; 1234,
  'host' =&gt; "0.0.0.0"
}).handler(VertxStomp::StompServerHandler.create(vertx)).listen()</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_closing_a_stomp_server">Closing a STOMP server</h3>
<div class="paragraph">
<p>STOMP servers are closed as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">server.close() { |ar_err,ar|
  if (ar_err == nil)
    puts "The STOMP server has been closed"
  else
    puts "The STOMP server failed to close : #{ar_err.get_message()}"
  end
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_configuration">Configuration</h3>
<div class="paragraph">
<p>The <code><a href="../dataobjects.html#StompServerOptions">StompServerOptions</a></code> let you configure some aspects of the STOMP server.</p>
</div>
<div class="paragraph">
<p>First, the STOMP server is based on a
<code><a href="../../yardoc/Vertx/NetServer.html">NetServer</a></code>, so you can configure the underlying <code><a href="../../yardoc/Vertx/NetServer.html">NetServer</a></code> from
the <code><a href="../dataobjects.html#StompServerOptions">StompServerOptions</a></code>. Alternatively you can also pass the
<code><a href="../../yardoc/Vertx/NetServer.html">NetServer</a></code> you want to use:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx, netServer).handler(VertxStomp::StompServerHandler.create(vertx)).listen()</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code><a href="../dataobjects.html#StompServerOptions">StompServerOptions</a></code> let you configure:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the host and port of the STOMP server - defaults to <code>0.0.0.0:61613</code>.</p>
</li>
<li>
<p>whether or not the STOMP server is secured - defaults to <code>false</code></p>
</li>
<li>
<p>the max STOMP frame body - default to 10 Mb</p>
</li>
<li>
<p>the maximum number of headers accepted in a STOMP frame - defaults to 1000</p>
</li>
<li>
<p>the max length of a header line in a STOMP frame - defaults to 10240</p>
</li>
<li>
<p>the STOMP heartbeat time - default to <code>1000, 1000</code></p>
</li>
<li>
<p>the supported STOMP protocol versions (1.0, 1.1 and 1.2 by default)</p>
</li>
<li>
<p>the maximum number of frame allowed in a transaction (defaults to 1000)</p>
</li>
<li>
<p>the size of the transaction chunk - defaults to 1000 (see
<code><a href="../dataobjects.html#StompServerOptions#set_transaction_chunk_size-instance_method">transactionChunkSize</a></code>)</p>
</li>
<li>
<p>the maximum number of subscriptions a client can handle - defaults to 1000</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The STOMP heartbeat is configured using a JSON object as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx, {
  'heartbeat' =&gt; {
    'x' =&gt; 1000,
    'y' =&gt; 1000
  }
}).handler(VertxStomp::StompServerHandler.create(vertx)).listen()</code></pre>
</div>
</div>
<div class="paragraph">
<p>Enabling security requires an additional <code><a href="../../yardoc/VertxAuthCommon/AuthProvider.html">AuthProvider</a></code> handling the
authentication requests:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx, {
  'secured' =&gt; true
}).handler(VertxStomp::StompServerHandler.create(vertx).auth_provider(provider)).listen()</code></pre>
</div>
</div>
<div class="paragraph">
<p>More information about <code><a href="../../yardoc/VertxAuthCommon/AuthProvider.html">AuthProvider</a></code> is available
<a href="http://vertx.io/docs/#authentication_and_authorisation">here</a>.</p>
</div>
<div class="paragraph">
<p>If a frame exceeds one of the size limits, the frame is rejected and the client receives an <code>ERROR</code> frame. As the
specification requires, the client connection is closed immediately after having sent the error. The same behavior
happens with the other thresholds.</p>
</div>
</div>
<div class="sect2">
<h3 id="_subscriptions">Subscriptions</h3>
<div class="paragraph">
<p>The default STOMP server handles subscription destination as opaque Strings. So it does not promote a structure
and it not hierarchic. By default the STOMP server follow a <em>topic</em> semantic (so messages are dispatched to all
subscribers).</p>
</div>
</div>
<div class="sect2">
<h3 id="_type_of_destinations">Type of destinations</h3>
<div class="paragraph">
<p>By default, the STOMP server manages <em>destinations</em> as topics. So messages are dispatched to all subscribers. You
can configure the server to use queues, or mix both types:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/destination'
require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx).handler(VertxStomp::StompServerHandler.create(vertx).destination_factory(lambda { |v,name|
  if (name.start_with?("/queue"))
    return VertxStomp::Destination.queue(vertx, name)
  else
    return VertxStomp::Destination.topic(vertx, name)
  end
})).listen()</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the last example, all destination starting with <code>/queue</code> are queues while others are topics. The destination is
created when the first subscription on this destination is received.</p>
</div>
<div class="paragraph">
<p>A server can decide to reject the destination creation by returning <code>null</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/destination'
require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx).handler(VertxStomp::StompServerHandler.create(vertx).destination_factory(lambda { |v,name|
  if (name.start_with?("/forbidden"))
    return nil
  elsif (name.start_with?("/queue"))
    return VertxStomp::Destination.queue(vertx, name)
  else
    return VertxStomp::Destination.topic(vertx, name)
  end
})).listen()</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this case, the subscriber received an <code>ERROR</code> frame.</p>
</div>
<div class="paragraph">
<p>Queues dispatches messages using a round-robin strategies.</p>
</div>
</div>
<div class="sect2">
<h3 id="_providing_your_own_type_of_destination">Providing your own type of destination</h3>
<div class="paragraph">
<p>On purpose the STOMP server does not implement any advanced feature. IF you need more advanced dispatching policy,
you can implement your own type of destination by providing a <code><a href="../../yardoc/VertxStomp/DestinationFactory.html">DestinationFactory</a></code>
returning your own <code><a href="../../yardoc/VertxStomp/Destination.html">Destination</a></code> object.</p>
</div>
</div>
<div class="sect2">
<h3 id="_acknowledgment">Acknowledgment</h3>
<div class="paragraph">
<p>By default, the STOMP server does nothing when a message is not acknowledged. You can customize this by
providing your own <code><a href="../../yardoc/VertxStomp/Destination.html">Destination</a></code> implementation.</p>
</div>
<div class="paragraph">
<p>The custom destination should call the</p>
</div>
<div class="paragraph">
<p><code><a href="../../yardoc/VertxStomp/StompServerHandler.html#on_ack-instance_method">onAck</a></code>
and
<code><a href="../../yardoc/VertxStomp/StompServerHandler.html#on_nack-instance_method">onNack</a></code>
method in order to let the <code><a href="../../yardoc/VertxStomp/StompServerHandler.html">StompServerHandler</a></code> customizes the behavior:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx).handler(VertxStomp::StompServerHandler.create(vertx).on_ack_handler() { |acknowledgement|
  # Action to execute when the frames (one in `client-individual` mode, several
  # in `client` mode are acknowledged.
}.on_nack_handler() { |acknowledgement|
  # Action to execute when the frames (1 in `client-individual` mode, several in
  # `client` mode are not acknowledged.
}).listen()</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_customizing_the_stomp_server">Customizing the STOMP server</h3>
<div class="paragraph">
<p>In addition to the handlers seen above, you can configure almost all aspects of the STOMP server, such as the
actions made when specific frames are received, the <code>ping</code> to sent to the client (to implement the heartbeat).
Here are some examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx).handler(VertxStomp::StompServerHandler.create(vertx).close_handler() { |connection|
  # client connection closed
}.begin_handler() { |frame|
  # transaction starts
}.commit_handler() { |frame|
  # transaction committed
}).listen()</code></pre>
</div>
</div>
<div class="paragraph">
<p>Be aware that changing the default behavior may break the compliance with the STOMP specification. So, please look
at the default implementations.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_stomp_client">STOMP client</h2>
<div class="sectionbody">
<div class="paragraph">
<p>STOMP clients connect to STOMP server and can send and receive frames.</p>
</div>
<div class="sect2">
<h3 id="_creating_a_stomp_client">Creating a STOMP client</h3>
<div class="paragraph">
<p>You create a <code><a href="../../yardoc/VertxStomp/StompClient.html">StompClient</a></code> instance with default options as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx).connect() { |ar_err,ar|
  if (ar_err == nil)
    connection = ar

  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The previous snippet creates a STOMP client connecting to "0.0.0.0:61613". Once connected, you get a
<code><a href="../../yardoc/VertxStomp/StompClientConnection.html">StompClientConnection</a></code> that let you interact with the server. You can
configure the host and port as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx).connect(61613, "0.0.0.0") { |ar_err,ar|
  if (ar_err == nil)
    connection = ar

  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>To catch connection errors due to authentication issues, or whatever error frames sent by the server during
the connection negotiation, you can register a <em>error handler</em> on the Stomp Client. All
connections created with the client inherit of the error handler (but can have their own):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx).error_frame_handler() { |frame|
  # Received the ERROR frame
}.connect(61613, "0.0.0.0") { |ar_err,ar|
  if (ar_err == nil)
    connection = ar

  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also configure the host and port in the <code><a href="../dataobjects.html#StompClientOptions">StompClientOptions</a></code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx, {
  'host' =&gt; "localhost",
  'port' =&gt; 1234
}).connect() { |ar_err,ar|
  if (ar_err == nil)
    connection = ar

  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_closing_a_stomp_client">Closing a STOMP client</h3>
<div class="paragraph">
<p>You can close a STOMP client:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx, {
  'host' =&gt; "localhost",
  'port' =&gt; 1234
}).connect() { |ar_err,ar|
  if (ar_err == nil)
    connection = ar

  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}

client.close()</code></pre>
</div>
</div>
<div class="paragraph">
<p>However, this way would not notify the server of the disconnection. To cleanly close the connection, you should
use the <code><a href="../../yardoc/VertxStomp/StompClientConnection.html#disconnect-instance_method">disconnect</a></code> method:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx, {
  'host' =&gt; "localhost",
  'port' =&gt; 1234
}).connect() { |ar_err,ar|
  if (ar_err == nil)
    connection = ar

    connection.disconnect()
  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If the heartbeat is enabled and if the client did not detect server activity after the configured timeout, the
connection is automatically closed.</p>
</div>
</div>
<div class="sect2">
<h3 id="_handling_errors">Handling errors</h3>
<div class="paragraph">
<p>On the <code><a href="../../yardoc/VertxStomp/StompClientConnection.html">StompClientConnection</a></code>, you can register an error handler receiving <code>ERROR</code>
frames sent by the server. Notice that the server closes the connection with the client after having sent such frame:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx, {
  'host' =&gt; "localhost",
  'port' =&gt; 1234
}).connect() { |ar_err,ar|
  if (ar_err == nil)
    connection = ar
    connection.error_handler() { |frame|
      puts "ERROR frame received : #{frame}"
    }
  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The client can also be notified when a connection drop has been detected. Connection failures are detected using the
STOMP heartbeat mechanism. When the server has not sent a message in the heartbeat time window, the connection is
closed and the <code>connectionDroppedHandler</code> is called (if set). To configure a <code>connectionDroppedHandler</code>, call
<code><a href="../../yardoc/VertxStomp/StompClientConnection.html#connection_dropped_handler-instance_method">connectionDroppedHandler</a></code>. The handler can
for instance tries to reconnect to the server:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx/buffer'
require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx).connect() { |ar_err,ar|
  if (ar_err == nil)
    connection = ar
    connection.connection_dropped_handler() { |con|
      # The connection has been lost
      # You can reconnect or switch to another server.
    }

    connection.send("/queue", Vertx::Buffer.buffer("Hello")) { |frame|
      puts "Message processed by the server"
    }
  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_configuration_2">Configuration</h3>
<div class="paragraph">
<p>You can configure various aspect by passing a
<code><a href="../dataobjects.html#StompClientOptions">StompClientOptions</a></code> when creating the <code><a href="../../yardoc/VertxStomp/StompClient.html">StompClient</a></code>. As the
STOMP client relies on a <code><a href="../../yardoc/Vertx/NetClient.html">NetClient</a></code>, you can configure the underlying Net Client from
the <code><a href="../dataobjects.html#StompClientOptions">StompClientOptions</a></code>. Alternatively, you can pass the <code><a href="../../yardoc/Vertx/NetClient.html">NetClient</a></code>
you want to use in the
<code><a href="../../yardoc/VertxStomp/StompClient.html#connect-instance_method">connect</a></code> method:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx).connect(netClient) { |ar_err,ar|
  if (ar_err == nil)
    connection = ar
    connection.error_handler() { |frame|
      puts "ERROR frame received : #{frame}"
    }
  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code><a href="../dataobjects.html#StompClientOptions">StompClientOptions</a></code> let you configure:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the host and port ot the STOMP server</p>
</li>
<li>
<p>the login and passcode to connect to the server</p>
</li>
<li>
<p>whether or not the <code>content-length</code> header should be added to the frame if not set explicitly. (enabled by default)</p>
</li>
<li>
<p>whether or not the <code>STOMP</code> command should be used instead of the <code>CONNECT</code> command (disabled by default)</p>
</li>
<li>
<p>whether or not the <code>host</code> header should be ignored in the <code>CONNECT</code> frame (disabled by default)</p>
</li>
<li>
<p>the heartbeat configuration (1000, 1000 by default)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_subscribing_to_destinations">Subscribing to destinations</h3>
<div class="paragraph">
<p>To subscribe to a destination, use:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx).connect() { |ar_err,ar|
  if (ar_err == nil)
    connection = ar
    connection.subscribe("/queue") { |frame|
      puts "Just received a frame from /queue : #{frame}"
    }
  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>To unsubscribe, use:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx).connect() { |ar_err,ar|
  if (ar_err == nil)
    connection = ar
    connection.subscribe("/queue") { |frame|
      puts "Just received a frame from /queue : #{frame}"
    }

    # ....

    connection.unsubscribe("/queue")
  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_sending_messages">Sending messages</h3>
<div class="paragraph">
<p>To send a message, use:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx/buffer'
require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx).connect() { |ar_err,ar|
  if (ar_err == nil)
    connection = ar
    headers = Hash.new()
    headers["header1"] = "value1"
    connection.send("/queue", headers, Vertx::Buffer.buffer("Hello"))
    # No headers:
    connection.send("/queue", Vertx::Buffer.buffer("World"))
  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_acknowledgements">Acknowledgements</h3>
<div class="paragraph">
<p>Clients can send <code>ACK</code> and <code>NACK</code> frames:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx).connect() { |ar_err,ar|
  if (ar_err == nil)
    connection = ar
    connection.subscribe("/queue") { |frame|
      connection.ack(frame['ack'])
      # OR
      connection.nack(frame['ack'])
    }
  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_transactions">Transactions</h3>
<div class="paragraph">
<p>Clients can also create transactions. <code>ACK</code>, <code>NACK</code> and <code>SEND</code> frames sent in the transaction will be delivery
only when the transaction is committed.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx/buffer'
require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx).connect() { |ar_err,ar|
  if (ar_err == nil)
    connection = ar
    headers = Hash.new()
    headers["transaction"] = "my-transaction"
    connection.begin_tx("my-transaction")
    connection.send("/queue", headers, Vertx::Buffer.buffer("Hello"))
    connection.send("/queue", headers, Vertx::Buffer.buffer("World"))
    connection.send("/queue", headers, Vertx::Buffer.buffer("!!!"))
    connection.commit("my-transaction")
    # OR
    connection.abort("my-transaction")
  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_receipt">Receipt</h3>
<div class="paragraph">
<p>Each sent commands can have a <em>receipt</em> handler, notified when the server has processed the message:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx/buffer'
require 'vertx-stomp/stomp_client'
client = VertxStomp::StompClient.create(vertx).connect() { |ar_err,ar|
  if (ar_err == nil)
    connection = ar

    connection.send("/queue", Vertx::Buffer.buffer("Hello")) { |frame|
      puts "Message processed by the server"
    }
  else
    puts "Failed to connect to the STOMP server: #{ar_err.to_string()}"
  end
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_using_the_stomp_server_as_a_bridge_to_the_vert_x_event_bus">Using the STOMP server as a bridge to the vert.x Event Bus</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The STOMP server can be used as a bridge to the vert.x Event Bus. The bridge is bi-directional meaning the STOMP
frames are translated to Event Bus messages and Event Bus messages are translated to STOMP frames.</p>
</div>
<div class="paragraph">
<p>To enable the bridge you need to configure the inbound and outbound addresses. Inbound addresses are STOMP
destination that are transferred to the event bus. The STOMP destination is used as the event bus address. Outbound
addresses are event bus addresses that are transferred to STOMP.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx).handler(VertxStomp::StompServerHandler.create(vertx).bridge({
  'inboundPermitteds' =&gt; [
    {
      'address' =&gt; "/toBus"
    }
  ],
  'outboundPermitteds' =&gt; [
    {
      'address' =&gt; "/toStomp"
    }
  ]
})).listen()</code></pre>
</div>
</div>
<div class="paragraph">
<p>By default, the bridge use a publish/subscribe delivery (topic). You can configure it to use a point to point
delivery where only one STOMP client or Event Bus consumer is invoked:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx).handler(VertxStomp::StompServerHandler.create(vertx).bridge({
  'inboundPermitteds' =&gt; [
    {
      'address' =&gt; "/toBus"
    }
  ],
  'outboundPermitteds' =&gt; [
    {
      'address' =&gt; "/toStomp"
    }
  ],
  'pointToPoint' =&gt; true
})).listen()</code></pre>
</div>
</div>
<div class="paragraph">
<p>The permitted options can also be expressed as a "regex" or with a <em>match</em>. A <em>match</em> is a structure that the
message payload must meet. For instance, in the next examples, the payload must contains the field "foo" set to
"bar". Structure match only supports JSON object.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx).handler(VertxStomp::StompServerHandler.create(vertx).bridge({
  'inboundPermitteds' =&gt; [
    {
      'address' =&gt; "/toBus",
      'match' =&gt; {
        'foo' =&gt; "bar"
      }
    }
  ],
  'outboundPermitteds' =&gt; [
    {
      'address' =&gt; "/toStomp"
    }
  ],
  'pointToPoint' =&gt; true
})).listen()</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_using_the_stomp_server_with_web_sockets">Using the STOMP server with web sockets</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you want to connect a JavaScript client (node.js or a browser) directly with the STOMP server, you can use a
web socket. The STOMP protocol has been adapted to work over web sockets in
<a href="http://jmesnil.net/stomp-websocket/doc/">StompJS</a>. The JavaScript connects directly to the STOMP server and send
STOMP frames on the web socket. It also receives the STOMP frame directly on the web socket.</p>
</div>
<div class="paragraph">
<p>To configure the server to use StompJS, you need to:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Enable the web socket bridge and configure the path of the listening web socket (<code>/stomp</code> by default).</p>
</li>
<li>
<p>Import <a href="http://jmesnil.net/stomp-websocket/doc/#download">StompJS</a> in your application (as a script on an
HTML page, or as an npm module (<a href="https://www.npmjs.com/package/stompjs" class="bare">https://www.npmjs.com/package/stompjs</a>).</p>
</li>
<li>
<p>Connect to the server</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>To achieve the first step, you would need a HTTP server, and pass the
<code><a href="../../yardoc/VertxStomp/StompServer.html#web_socket_handler-instance_method">webSocketHandler</a></code> result to
<code><a href="../../yardoc/Vertx/HttpServer.html#websocket_handler-instance_method">websocketHandler</a></code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
server = VertxStomp::StompServer.create(vertx, {
  'port' =&gt; -1,
  'websocketBridge' =&gt; true,
  'websocketPath' =&gt; "/stomp"
}).handler(VertxStomp::StompServerHandler.create(vertx))

http = vertx.create_http_server({
  'websocketSubProtocols' =&gt; "v10.stomp, v11.stomp"
}).websocket_handler(&amp;server.web_socket_handler()).listen(8080)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Don&#8217;t forget to declare the supported sub-protocols. Without this, the connection will be rejected.</p>
</div>
<div class="paragraph">
<p>Then follow the instructions from  <a href="http://jmesnil.net/stomp-websocket/doc/">the StompJS documentation</a> to connect to
the server. Here is a simple example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-javascript" data-lang="javascript">var url = "ws://localhost:8080/stomp";
var client = Stomp.client(url);
var callback = function(frame) {
   console.log(frame);
};

client.connect({}, function() {
 var subscription = client.subscribe("foo", callback);
});</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_registering_received_and_writing_frame_handlers">Registering received and writing frame handlers</h2>
<div class="sectionbody">
<div class="paragraph">
<p>STOMP clients, client&#8217;s connections and server handlers support registering a received
<code><a href="../dataobjects.html#Frame">Frame</a></code> handler that would be notified every time a frame is received from the wire. It lets
you log the frames, or implement custom behavior. The handler is already called for <code>PING</code>
frames, and <em>illegal / unknown</em> frames:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
require 'vertx-stomp/stomp_client'
server = VertxStomp::StompServer.create(vertx).handler(VertxStomp::StompServerHandler.create(vertx).received_frame_handler() { |sf|
  puts sf.frame()
}).listen()

client = VertxStomp::StompClient.create(vertx).received_frame_handler() { |frame|
  puts frame
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The handler is called before the frame is processed, so you can also <em>modify</em> the frame.</p>
</div>
<div class="paragraph">
<p>Frames not using a valid STOMP command use the <code>UNKNOWN</code> command. The original command is written
in the headers using the <code><a href="todo">Frame.STOMP_FRAME_COMMAND</a></code> key.</p>
</div>
<div class="paragraph">
<p>You can also register a handler to be notified when a frame is going to be sent (written to the wire):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-stomp/stomp_server_handler'
require 'vertx-stomp/stomp_server'
require 'vertx-stomp/stomp_client'
server = VertxStomp::StompServer.create(vertx).handler(VertxStomp::StompServerHandler.create(vertx)).writing_frame_handler() { |sf|
  puts sf.frame()
}.listen()

client = VertxStomp::StompClient.create(vertx).writing_frame_handler() { |frame|
  puts frame
}</code></pre>
</div>
</div>
</div>
</div>

        

        
          <div id="footer">
            <div id="footer-text">
              
                Last updated 2016-09-12 08:38:04 CEST
              
              
            </div>
          </div>
        
      </div>
    </div>
  </div>
</div>

<footer>
  <div class="container">
    <div class="row">
      <div class="col-xs-6 col-sm-3 col-md-3 col-lg-2">
        <h2>Vert.x</h2>
        <ul class="list-unstyled">
          <li><a href="http://vertx.io/">Home</a></li>
          <li><a href="http://vertx.io/download/">Download</a></li>
          <li><a href="http://vertx.io/docs/">Documentation</a></li>
          <li><a href="https://github.com/vert-x3/wiki/wiki">Wiki</a></li>
          <li><a href="http://vertx.io/blog/">Blog</a></li>
          <li><a href="http://vertx.io/vertx2/" class="vertx-2-link">Vert.x 2</a></li>
        </ul>
      </div>
      <div class="col-xs-6 col-sm-3 col-md-3 col-lg-2">
        <h2>Community</h2>
        <ul class="list-unstyled">
          <li><a href="http://vertx.io/community/">Help &amp; Contributors</a></li>
          <li><a href="http://vertx.io/materials/">Learning materials</a></li>
          <li><a href="https://groups.google.com/forum/?fromgroups#!forum/vertx">User Group</a></li>
          <li><a href="https://groups.google.com/forum/?fromgroups#!forum/vertx-dev">Developer Group</a></li>
        </ul>
      </div>

      <div class="col-xs-12 col-sm-6 col-lg-offset-2 col-md-6 copyright">
        <p>Vert.x is open source and dual licensed under the <a href="https://www.eclipse.org/org/documents/epl-v10.php">Eclipse Public License 1.0</a> and <a href="https://www.apache.org/licenses/LICENSE-2.0.html">Apache License 2.0</a>.</p>
        <p>This website is licensed under the <a href="http://creativecommons.org/licenses/by-sa/3.0/">CC BY-SA 3.0 License</a>.<br>
        Design by <a href="http://www.michel-kraemer.com">Michel Kr&auml;mer</a>. <a href="http://www.entypo.com">Entypo pictograms</a> by Daniel Bruce.</p>
        <div class="row">
          <div class="col-xs-12 col-lg-offset-1 col-md-5">
            <a href="http://eclipse.org">
            <img class="logo eclipse-logo" src="http://vertx.io/assets/eclipse_logo_grey_small.png" width="204" height="48">
            </a>
          </div>
          <div class="col-xs-12 col-md-offset-2 col-lg-offset-0 col-md-5">
            <a href="http://cloudbees.com">
            <img class="logo cloudbees-logo" src="http://vertx.io/assets/Button-Built-on-CB-1-grey.png" width="180" height="48">
           </a>
          </div>
          <div class="col-xs-12 col-md-offset-2 col-lg-offset-1 col-md-5 jprofiler">
            <a href="http://www.ej-technologies.com/products/jprofiler/overview.html"
            style="text-decoration:none">
            <img class="logo jprofiler-logo" src="http://vertx.io/assets/jprofiler-logo.png" width="48" height="48"><span class="jprofiler-logo">&nbsp; JPROFILER</span>
            </a>
          </div>
        </div>
      </div>
    </div>
  </div>
</footer>

<script src="http://static.jboss.org/theme/js/libs/jquery/jquery-1.9.1.min.js"></script>
<script src="http://vertx.io/javascripts/bootstrap.min.js"></script>
<script src="http://vertx.io/javascripts/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>



<script src="http://vertx.io/javascripts/sidebar.js"></script>


</body>
</html>
